/* 
 * File:   DuplicateStackCommand.cpp
 * Author: Gab'z
 * 
 * Created on 5 juin 2012, 02:36
 */

#include "DuplicateStackCommand.h"
#include "../../Context.h"
#include "../../command/literal/StackList.h"
#include "../../memento/EmptyMemento.h"
#include "../../../exception/MementoException.h"

namespace calculator {

    DuplicateStackCommand::DuplicateStackCommand(const std::string name) : StackListCommand(name) {
    }

    DuplicateStackCommand::DuplicateStackCommand(const DuplicateStackCommand& orig) : StackListCommand(orig._name) {
    }

    DuplicateStackCommand::~DuplicateStackCommand() {
    }

    DuplicateStackCommand* DuplicateStackCommand::clone() const {
        return new DuplicateStackCommand(_name);
    }

    std::string DuplicateStackCommand::isExecutable() const {
        if (Context::getInstance()->getStackList()->size() == 0) return "Error : no stack";
        return "";
    }

    const Memento* DuplicateStackCommand::createMemento() const throw (CommandException) {
        return new EmptyMemento(clone());
    }

    void DuplicateStackCommand::restoreFromMemento(const Memento* memento) const throw (MementoException) {
        const EmptyMemento* emptyMemento = dynamic_cast<const EmptyMemento*> (memento);
        if (emptyMemento == 0) {
            std::string str = "Bad Memento type, expected : EmptyMemento, was ";
            str += typeid (*memento).name();
            throw MementoException(str);
        }
        Context::getInstance()->getStackList()->removeCurrentStack();
        if (Context::getInstance()->getStackList()->getCurrentStackIndex() != 0) {
            Context::getInstance()->setCurrentStack(Context::getInstance()->getStackList()->getCurrentStackIndex() - 1);
        }
    }

    void DuplicateStackCommand::apply(StackList* stacklist) const throw (CommandException) {
        if (stacklist->size() == 0) throw CommandException("There must be at least one Stack");
        stacklist->duplicateCurrentStack();
    }
}